<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>12 发布订阅1</title>
</head>

<body>
  <button class="btn3">通知执行</button>
  <script>
    const btn3 = document.querySelector(".btn3");
    (() => {
      class Sub {
        constructor() {
          // 创建事件池（关键就是这个结构的设计）
          this.pond = {};
          // {
          //   'AAA': [fn1, fn2, ...],
          //    'BBB': [fn1, fn2, ...]
          // }
        }
        on(event, func) {
          let pond = this.pond;
          !pond.hasOwnProperty(event) ? pond[event] = [] : null;
          let arr = pond[event] || [];
          !arr.includes(func) ? arr.push(func) : null;
        }
        off(event, func) {
          let pond = this.pond;
          if (!pond.hasOwnProperty(event)) return;
          let arrs = pond[event] || [];
          pond[event] = arrs.filter(arr => arr !== func);
        }
        emit(event, ...params) {
          let pond = this.pond;
          if (!pond.hasOwnProperty(event)) return;
          let arrs = pond[event] || [];
          arrs.forEach(arr => arr(...params));
        }
      }
      window.subscribe = () => new Sub;
    })();

    let fn1 = (x, y) => console.log('fn1', x, y);
    let fn2 = () => {
      console.log('fn2')
      sub1.off('AAA', fn1);
      sub1.off('AAA', fn2);
    };
    let fn3 = () => console.log('fn3');
    let fn4 = () => console.log('fn4');
    let fn5 = (x, y) => console.log('fn5', x, y);

    let sub1 = subscribe();
    let sub2 = subscribe();

    sub1.on('AAA', fn1);
    sub1.on('AAA', fn2);
    sub1.on('AAA', fn3);
    sub1.on('AAA', fn4);
    sub1.on('BBB', fn5);

    sub2.on('CCC', fn5);

    // setTimeout(() => {
    //   sub1.emit('AAA', 10, 20);
    // })

    btn3.addEventListener("click", function () {
      sub1.emit('AAA', 10, 20);
      sub1.emit('BBB', 100, 200);
      sub2.emit('CCC', 1000, 2000);
    })
  </script>
</body>

</html>